package online.afeibaili.storebackendframework.controller

import com.fasterxml.jackson.annotation.JsonIgnoreProperties
import com.fasterxml.jackson.annotation.JsonProperty
import online.afeibaili.storebackendframework.controller.util.JSON
import online.afeibaili.storebackendframework.controller.util.keyAndSecretRequest
import online.afeibaili.storebackendframework.model.AccountEntity
import online.afeibaili.storebackendframework.service.impl.AccountServiceImpl
import online.afeibaili.storebackendframework.util.*
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.*


/**
 * 账户控制类
 *
 *@author AfeiBaili
 *@version 2025/10/17 14:51
 */

@RestController
@RequestMapping("/account")
class AccountController {
    val loginUrl = "https://api.weixin.qq.com/sns/jscode2session"

    @Autowired
    lateinit var service: AccountServiceImpl

    /**
     * ## 微信授权登录
     *
     * @param appid 小程序id
     * @param secret 小程序secret
     * @param code 小程序传进的login代码
     * @param userInfo 小程序传进的用户信息
     *
     * @return 成功返回用户信息
     * - 如果校验id出错返回400
     * - 如果账户已存在返回401
     */
    @PostMapping("/register/wx")
    fun register(
        @RequestParam appid: String,
        @RequestParam secret: String,
        @RequestParam code: String,
        @RequestParam userInfo: String,
    ): ResponseEntity<Map<String, Any>> {
        val responseBody: String = keyAndSecretRequest(
            "${loginUrl}?appid=${appid}&secret=${secret}&js_code=${code}&grant_type=authorization_code"
        )
        val userInfoObj: UserInfo = UserInfo.fromJson(userInfo)
        val idObj: MiniProgramInfo = MiniProgramInfo.fromJson(responseBody)

        if (idObj.openid == "") return 400 message "获取校验id出错"
        val avatar: String = saveAvatar(userInfoObj.nickName, userInfoObj.avatarUrl)
        val entity = AccountEntity(idObj.openid, userInfoObj.nickName, avatar)
        val accountEntity: AccountEntity? = service.getOrCreate(entity)
        if (accountEntity == null) return 401 message "账户已存在"

        logger.info("注册一个用户：$accountEntity")

        return ok(200, accountEntity)
    }

    /**
     * ## 微信自动登录
     *
     * @param openid 小程序用户唯一id
     *
     * @return 如果找不到用户返回400
     */
    @PostMapping("/login/auto")
    fun autoLogin(@RequestParam openid: String) = response {
        val entity: AccountEntity? = service.getById(openid)
        if (entity == null) return@response 400 message "找不到用户"
        service.updateLastLoginTime(openid)
        200 data entity
    }

    @PostMapping("/register")
    fun create(@RequestBody account: AccountEntity): ResponseEntity<Map<String, Any>> {
        val objOrNull: AccountEntity? = service.getOrCreate(account)
        if (objOrNull == null) return ok(400, "对象已存在")
        return ok(200, account)
    }

    @PostMapping("/login")
    fun login(@RequestParam id: String): ResponseEntity<Map<String, Any>> {
        val entity: AccountEntity? = service.getById(id)
        if (entity == null) return ok(400, "找不到对象")
        return ok(200, entity)
    }
}

/** 实体映射对象 */
@JsonIgnoreProperties(ignoreUnknown = true)
class UserInfo() {
    var nickName: String = ""
    var avatarUrl: String = ""

    @JsonProperty("is_demote")
    var isDemote: Boolean = false
    var gender: Int = 0
    var language: String = ""
    var city: String = ""
    var province: String = ""
    var country: String = ""

    companion object {
        fun fromJson(json: String): UserInfo =
            JSON.readValue(json, UserInfo::class.java)
    }
}

class MiniProgramInfo() {
    @JsonProperty("session_key")
    var sessionKey: String = ""
    var openid: String = ""


    companion object {
        fun fromJson(json: String): MiniProgramInfo =
            JSON.readValue(json, MiniProgramInfo::class.java)
    }
}